package com.itlong.cloud.utils.file;

import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.random.RandomUtil;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * <desc>
 *      文件上传帮助类。
 * </desc>
 *
 * @createDate 2017/10/11
 */
public class UploadFileUtil {


    /**
     * <desc>
     *      FTP文件上传。
     * <desc/>
     *
     * @param uploadFile 内部类
     * @return Map 包含returnCode 返回操作结果,accessPath 文件访问路径。
     * @author Wenchao.L
     * @createDate 2017/10/11
     */
    public static Map<String, Object> uploadFile(UploadFile uploadFile) throws IOException {
        Map<String, Object> resultMap = new HashMap<>();
        boolean success = false;
        FTPClient ftp = new FTPClient();
        try {
            int reply;
            ftp.setConnectTimeout(PlatformConstants.FILE_FTP_TIME_OUT);
            ftp.connect(uploadFile.getHost(), Integer.parseInt(uploadFile.getPort()));
            ftp.login(uploadFile.getUserName(), uploadFile.getPassWord());
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                resultMap.put("returnCode", success);
            }
            StringBuffer fileName = new StringBuffer();
            StringBuffer accessPath = new StringBuffer();
            //文件处理
            Date currentDate = new Date();
            String folderPath = DateFormatUtils.format(currentDate, DateUtil.YYMMDD);
            //组装文件名
            fileName.append(DateFormatUtils.format(currentDate, DateUtil.YYMMDDHHMMSS)).
                    append(RandomUtil.getRandomStringByLength(4)).append(".");
            String ftpDirName = uploadFile.getFileCatalogEnum() + folderPath;

            // 设置上传目录(没有则创建)
            StringTokenizer s = new StringTokenizer(ftpDirName, "/");
            s.countTokens();
            String pathName = "";
            while (s.hasMoreElements()) {
                pathName = String.format("%s/%s",pathName,s.nextElement());
                try {
                    ftp.mkd(pathName);
                } catch (Exception ex) {
                    throw new IOException("【文件创建失败】", ex);
                }
            }
            //设置文件目录
            ftp.changeWorkingDirectory(ftpDirName);
            //ftp默认是文本类型，所以需要设置支持图片类型，否则会花图
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            //上传文件并设置名称
            ftp.storeFile(fileName.toString() + uploadFile.getFileSuffix(), uploadFile.getInputStream());
            uploadFile.getInputStream().close();
            ftp.logout();
            success = true;
            resultMap.put("returnCode", success);
            resultMap.put("accessPath", accessPath.
                    append(uploadFile.getAccessUrl()).
                    append(uploadFile.getFileCatalogEnum()).
                    append(folderPath).append("/").
                    append(fileName.toString()).
                    append(uploadFile.getFileSuffix()));
            return resultMap;
        } catch (IOException ex) {
            throw new IOException("【文件上传失败】", ex);
        } finally {
            if (ftp.isConnected()) {
                ftp.disconnect();
            }
        }
    }

    public static boolean deleteFile(UploadFile uploadFile, String pathname, String filename){
        FTPClient ftp = new FTPClient();
        boolean flag = false;
        try {
            ftp.setConnectTimeout(PlatformConstants.FILE_FTP_TIME_OUT);
            ftp.connect(uploadFile.getHost(), Integer.parseInt(uploadFile.getPort()));
            ftp.login(uploadFile.getUserName(), uploadFile.getPassWord());
            //切换FTP目录
            ftp.changeWorkingDirectory(pathname);
            ftp.dele(filename);
            ftp.logout();
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(ftp.isConnected()){
                try{
                    ftp.disconnect();
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
        }
        return flag;
    }



    /**
     * <desc>
     *      获取文件的后缀。
     * <desc/>
     *
     * @param fileName 文件名称
     * @return
     * @author Wenchao.L
     * @createDate 2017/10/11
     */
    public static String getFileSuffix(String fileName) {
        if (StringUtils.isNotBlank(fileName)) {
            return fileName.substring(fileName.lastIndexOf(".") + 1);
        }
        return null;
    }


    /**
     * <desc>
     *      上传文件工具的内部类。
     * </desc>
     *
     * @createDate 2017/10/11
     */
    @Data
    @NoArgsConstructor
    public class UploadFile {

        private String host;        //ftp 域名
        private String userName;    //ftp 登录名
        private String passWord;    //ftp 密码
        private String port;         //ftp 端口
        private InputStream inputStream;    //输入流
        private String fileSuffix;          //文件后缀
        private String accessUrl;           //访问域名
        private String fileCatalogEnum;    //业务根目录

        public UploadFile(String host, String userName, String passWord, String port, InputStream inputStream, String fileSuffix, String accessUrl, String fileCatalogEnum) {
            this.host = host;
            this.userName = userName;
            this.passWord = passWord;
            this.port = port;
            this.inputStream = inputStream;
            this.fileSuffix = fileSuffix;
            this.accessUrl = accessUrl;
            this.fileCatalogEnum = fileCatalogEnum;
        }

        public UploadFile(String host, String userName, String passWord, String port) {
            this.host = host;
            this.userName = userName;
            this.passWord = passWord;
            this.port = port;
        }

    }

}
